package org.example;

import com.sun.tools.attach.*;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.Date;
import java.util.List;

/**
 * Hello world!
 *
 */
public class App {
    //-javaagent
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("agentArgs : " + agentArgs);
        inst.addTransformer(new DefineTransformer(), true);
    }

    //java attach
    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("agentmain : " + agentArgs);

        Class[] allLoadedClasses = inst.getAllLoadedClasses();
        for (Class allLoadedClass : allLoadedClasses) {
            System.out.println(allLoadedClass.getSimpleName());
        }

        inst.addTransformer(new DefineTransformer(), true);
    }

    static class DefineTransformer implements ClassFileTransformer {

        @Override
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
            System.out.println("premain load Class:" + className);
//            if (className.equals("org/example/ChangeTest")) {
//                try {
//                    // 从ClassPool获得CtClass对象
//                    final ClassPool classPool = ClassPool.getDefault();
//                    final CtClass clazz = classPool.get("org.example.ChangeTest");
//                    CtMethod convertToAbbr = clazz.getDeclaredMethod("doSomething");
//
//                    String methodBody = "{" +
//                            "        long start = System.currentTimeMillis();" +
//                            "        Thread.sleep(1000);" +
//                            "        System.out.println(System.currentTimeMillis() - start);" +
//                            "    }";
//
//                    convertToAbbr.setBody(methodBody);
//
//                    // 返回字节码，并且detachCtClass对象
//                    byte[] byteCode = clazz.toBytecode();
//                    //detach的意思是将内存中曾经被javassist加载过的对象移除，如果下次有需要在内存中找不到会重新走javassist加载
//                    clazz.detach();
//                    return byteCode;
//                } catch (Exception ex) {
//                    ex.printStackTrace();
//                }
//            }
            return classfileBuffer;
        }


    }

    public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {

        VirtualMachineDescriptor design = null;
        List<VirtualMachineDescriptor> list = VirtualMachine.list();
        for (VirtualMachineDescriptor virtualMachineDescriptor : list) {

            if (virtualMachineDescriptor.displayName().contains("MainDesign")) {
                design = virtualMachineDescriptor;
            }
        }

        VirtualMachine virtualMachine = VirtualMachine.attach(design.id());
        virtualMachine.loadAgent("C:\\Users\\叶英明\\Desktop\\idea项目\\agentDemo\\target\\agentDemo-1.0-SNAPSHOT.jar");
        int a = 1;
    }
}